package com.terminee.activities;

import java.util.Hashtable;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.google.gson.Gson;
import com.terminee.model.ClientTerm;
import com.terminee.threads.BackendThread;
import com.terminee.threads.BackendThread.BackendThreadMessages;
import com.terminee.threads.BackendThread.BackendThreadModes;

public class TermineeInput extends Activity {

	// different types of dialogs
	static final int SUBMIT_PROGRESS_DIALOG = 0;
	static final int NO_TERM_DIALOG = 1;
	static final int NO_DEFINITION_DIALOG = 2;
	static final int TROUBLE_SUBMITTING_DEFINITION = 3;
	static final int SUBMISSION_SUCCESSFUL = 4;
	
	// view components
	private EditText termText;
	private EditText definitionText;
	private Button submitButton;
	private Button cancelButton;
	private InputMethodManager softKeyboard;
	
	// Define the Handler that receives messages from the search thread and update the progress
    final Handler handler = new Handler() { public void handleMessage(Message msg) { handleBackendThreadMessage(msg);}};
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.terminee_input);
	    
	    // get view component references
	    termText = (EditText) findViewById(R.id.TermEditText);
		definitionText = (EditText) findViewById(R.id.DefinitionEditText);
		submitButton = (Button) findViewById(R.id.SubmitButton);
		cancelButton = (Button) findViewById(R.id.CancelButton);
		
		// get system services
		softKeyboard = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
	    
		// populate term field with passed in term if there is one
		Bundle extras = getIntent().getExtras();
	    if (extras != null) {
	    	String word = extras.getString("term");
	    	if(word != null && word.length() > 0) {
	    		termText.setText(word);
	    		termText.setTextColor(Color.BLACK);
	    	}
	    }
	    
	    // term text key listener
	    termText.setOnKeyListener(new OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				
				// When Enter is pressed hide softkeyboard, lose focus, and search for term definitions
				if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
					definitionText.requestFocus();
					return true;
				}
				return false;
			}
		});
	    
	    // term text change listener
	    termText.setOnFocusChangeListener(new OnFocusChangeListener() {
			public void onFocusChange(View v, boolean hasFocus) {

				// if gets focus and default search string is there remove it and set text to black
				if (hasFocus && ((EditText) v).getText().toString().
						equalsIgnoreCase(getResources().getString(R.string.term_default))) {
					termText.setText("", TextView.BufferType.EDITABLE);
					termText.setTextColor(Color.BLACK);
				}
			}
		});
	    
	    // definition text key listener
	    definitionText.setOnKeyListener(new OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				
				// When Enter is pressed hide softkeyboardand give focus to submit button
				if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
					softKeyboard.hideSoftInputFromWindow(v.getWindowToken(), 0);
					submitButton.requestFocus();
					return true;
				}
				return false;
			}
		});
	    
	    // definition text change listener
	    definitionText.setOnFocusChangeListener(new OnFocusChangeListener() {
			public void onFocusChange(View v, boolean hasFocus) {

				// if gets focus and default definition string is there remove it and set text to black
				if (hasFocus && ((EditText) v).getText().toString().
						equalsIgnoreCase(getResources().getString(R.string.definition_default))) {
					definitionText.setText("", TextView.BufferType.EDITABLE);
					definitionText.setTextColor(Color.BLACK);
				}
			}
		});
	    
	    // return to previous activity if cancel button is clicked
		cancelButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { finish(); }});
		
		// start searching when search button is clicked
		submitButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { submitDefinition(v); }});
	}
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.input_menu, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.SearchMenuItem:
        	searchTerms();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }
    
    /**
     * Go to search screen
     */
    private void searchTerms() {
    	Intent termineeLauncher = new Intent(this, TermineeLauncher.class);
 	   	startActivity(termineeLauncher);
    }
	
    /**
     * Submit a definition
     * 
     * @param v View for dismissing soft keyboard
     */
	private void submitDefinition(View v) {
		submitButton.setClickable(false);
		softKeyboard.hideSoftInputFromWindow(v.getWindowToken(), 0);
		
		if(termText.getText().toString().length() < 1 || termText.getTextColors().getDefaultColor() == Color.LTGRAY) {
			showDialog(NO_TERM_DIALOG);
			submitButton.setClickable(true);
			return;
		}
		
		if(definitionText.getText().toString().length() < 1 || definitionText.getTextColors().getDefaultColor() == Color.LTGRAY) {
			showDialog(NO_DEFINITION_DIALOG);
			submitButton.setClickable(true);
			return;
		}
		
		showDialog(SUBMIT_PROGRESS_DIALOG);
		submitButton.setClickable(true);
		
		// extract definition
		ClientTerm term = new ClientTerm();
		term.setWord(termText.getText().toString());
		term.setDefinition(definitionText.getText().toString());
		Gson gson = new Gson();
		String json = gson.toJson(term);
		
		Hashtable<String,Object> extraParams = new Hashtable<String, Object>();
		Uri.Builder uriBuilder = new Uri.Builder();
		uriBuilder = uriBuilder.encodedPath(getResources().getString(R.string.terminee_prod_host) + "resources/terminee/add");
		extraParams.put("uriBuilder", uriBuilder);
		extraParams.put("json", json);
	    
	    // start up thread 
		BackendThread thread = new BackendThread(handler, BackendThreadModes.SubmitDefinition, extraParams);
		thread.start();
	}
	
	/**
	 * Handle message return from threads
	 * @param msg Message returned from thread
	 */
	private void handleBackendThreadMessage(Message msg) {
		dismissDialog(SUBMIT_PROGRESS_DIALOG);
		switch((BackendThreadMessages)msg.getData().getSerializable("message type")) {
		case SearchSuccessful:
			break;
		case TroubleSubmittingDefinition:
			showDialog(TROUBLE_SUBMITTING_DEFINITION);
			break;
		case SubmitSuccessful:
			showDialog(SUBMISSION_SUCCESSFUL);
			break;
		}
	}
	
	/**
	 * Creates dialogs
	 */
	@Override
	protected Dialog onCreateDialog(int id) {
		Dialog dialog = null;
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		switch (id) {
		case SUBMIT_PROGRESS_DIALOG:
			ProgressDialog progressDialog = new ProgressDialog(this);
			progressDialog.setMessage("Submitting definition. Please wait...");
			progressDialog.setCancelable(false);
			dialog = progressDialog;
			break;
		case NO_TERM_DIALOG:
			// build alert dialog with error message and ok button
			builder.setMessage("You must enter a term to define.")
		       .setCancelable(false)
		       .setNeutralButton("Ok", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		        	   dismissDialog(NO_TERM_DIALOG);
		           }
		       });
			dialog = builder.create();
			break;
		case NO_DEFINITION_DIALOG:
			// build alert dialog with error message and ok button
			builder.setMessage("You must enter a definition for the term.")
		       .setCancelable(false)
		       .setNeutralButton("Ok", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		        	   dismissDialog(NO_DEFINITION_DIALOG);
		           }
		       });
			dialog = builder.create();
			break;
		case TROUBLE_SUBMITTING_DEFINITION:
			// build alert dialog with error message and ok button
			builder.setMessage("Trouble submitting definition. Please try again")
		       .setCancelable(false)
		       .setNeutralButton("Ok", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		        	   dismissDialog(TROUBLE_SUBMITTING_DEFINITION);
		           }
		       });
			dialog = builder.create();
			break;
		case SUBMISSION_SUCCESSFUL:
			// build alert dialog with error message and ok button
			builder.setMessage("Submission Successful. Thanks")
		       .setCancelable(false)
		       .setNeutralButton("Ok", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		        	   dismissDialog(SUBMISSION_SUCCESSFUL);
		        	   setResult(RESULT_OK);
		        	   finish();
		           }
		       });
			dialog = builder.create();
			break;
		}

		return dialog;
	}

	@Override
    protected void onRestoreInstanceState (Bundle savedInstanceState) {
    	super.onRestoreInstanceState(savedInstanceState);
    	
    	// change font to black if not default term, (for orientation changes)
		if(!termText.getText().toString().
				equalsIgnoreCase(getResources().getString(R.string.term_default))) {
			termText.setTextColor(Color.BLACK);
		}
		
		// change font to black if not default definition, (for orientation changes)
		if(!definitionText.getText().toString().
				equalsIgnoreCase(getResources().getString(R.string.definition_default))) {
			definitionText.setTextColor(Color.BLACK);
		}
    }
}
